package com.fish.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fish.common.exception.BusinessException;
import com.fish.common.result.ResultCode;
import com.fish.dao.mapper.DictDataMapper;
import com.fish.dao.mapper.DictTypeMapper;
import com.fish.model.dto.DictTypeDTO;
import com.fish.model.entity.DictData;
import com.fish.model.entity.DictType;
import com.fish.model.vo.DictTypeVO;
import com.fish.service.DictTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import jakarta.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典类型服务实现类
 */
@Service
public class DictTypeServiceImpl implements DictTypeService {

    @Resource
    private DictTypeMapper dictTypeMapper;

    @Resource
    private DictDataMapper dictDataMapper;

    @Override
    public Page<DictTypeVO> getPage(Integer pageNum, Integer pageSize, String dictName, String dictType) {
        Page<DictType> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<DictType> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(dictName), DictType::getDictName, dictName)
                .like(StringUtils.hasText(dictType), DictType::getDictType, dictType)
                .orderByDesc(DictType::getCreateTime);
        
        Page<DictType> dictTypePage = dictTypeMapper.selectPage(page, wrapper);
        
        Page<DictTypeVO> voPage = new Page<>();
        BeanUtils.copyProperties(dictTypePage, voPage, "records");
        
        List<DictTypeVO> voList = dictTypePage.getRecords().stream().map(dictTypeEntity -> {
            DictTypeVO vo = new DictTypeVO();
            BeanUtils.copyProperties(dictTypeEntity, vo);
            return vo;
        }).collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public List<DictTypeVO> getAll() {
        List<DictType> list = dictTypeMapper.selectList(
            new LambdaQueryWrapper<DictType>()
                .eq(DictType::getStatus, 1)
                .orderByAsc(DictType::getDictType)
        );
        
        return list.stream().map(dictType -> {
            DictTypeVO vo = new DictTypeVO();
            BeanUtils.copyProperties(dictType, vo);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public DictTypeVO getById(Long id) {
        DictType dictType = dictTypeMapper.selectById(id);
        if (dictType == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        
        DictTypeVO vo = new DictTypeVO();
        BeanUtils.copyProperties(dictType, vo);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DictTypeDTO dto) {
        // 检查字典类型是否已存在
        LambdaQueryWrapper<DictType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DictType::getDictType, dto.getDictType());
        Long count = dictTypeMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException(ResultCode.ERROR.getCode(), "字典类型已存在");
        }
        
        DictType dictType = new DictType();
        BeanUtils.copyProperties(dto, dictType);
        dictTypeMapper.insert(dictType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DictTypeDTO dto) {
        if (dto.getId() == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "字典类型ID不能为空");
        }
        
        DictType existDictType = dictTypeMapper.selectById(dto.getId());
        if (existDictType == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        
        // 检查字典类型是否被其他记录使用
        LambdaQueryWrapper<DictType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DictType::getDictType, dto.getDictType())
                .ne(DictType::getId, dto.getId());
        Long count = dictTypeMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException(ResultCode.ERROR.getCode(), "字典类型已存在");
        }
        
        DictType dictType = new DictType();
        BeanUtils.copyProperties(dto, dictType);
        dictTypeMapper.updateById(dictType);
        
        // 如果字典类型发生变化，需要更新字典数据表中的字典类型
        if (!existDictType.getDictType().equals(dto.getDictType())) {
            DictData updateDictData = new DictData();
            updateDictData.setDictType(dto.getDictType());
            
            LambdaQueryWrapper<DictData> dataWrapper = new LambdaQueryWrapper<>();
            dataWrapper.eq(DictData::getDictType, existDictType.getDictType());
            dictDataMapper.update(updateDictData, dataWrapper);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        DictType dictType = dictTypeMapper.selectById(id);
        if (dictType == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        
        // 检查是否有关联的字典数据
        LambdaQueryWrapper<DictData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DictData::getDictType, dictType.getDictType());
        Long count = dictDataMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException(ResultCode.ERROR.getCode(), "该字典类型下存在字典数据，无法删除");
        }
        
        dictTypeMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Long> ids) {
        for (Long id : ids) {
            delete(id);
        }
    }
}